﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;
using Revis.VClinicNet.Core.Domain.Repository;
using Revis.VClinicNet.Core.Domain.Credentials;
using Revis.VClinicNet.Core.Domain;

namespace Revis.VClinicNet.App.Internal.ServiceImpl
{
    public class DataService : IDataService
    {
        private IWorkerUserRepository _userRepository = null;
        private IPatientUserRepository _patientUserRepository = null;
        private IVisitRepository _visitRepository = null;
        private IEntryRepository _entryRepository = null;
        private IPasswordEncrypter _password = null;

        public DataService(
            IWorkerUserRepository userRepository,
            IPatientUserRepository patientUserRepository,
            IVisitRepository visitRepository,
            IEntryRepository entryRepository,
            IPasswordEncrypter passwordEncrypter
            )
        {
            _userRepository = userRepository;
            _patientUserRepository = patientUserRepository;
            _visitRepository = visitRepository;
            _entryRepository = entryRepository;
            _password = passwordEncrypter;
        }

        public void FillUp()
        {
            Reset();

            DateTime today = DateTime.Today;

            //Pracownicy/użytkownicy 

            Doctor doctor1 = new Doctor("Marcin", "Kramel");
            foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))) {
                WorkTime workTime = doctor1.GetWorkTime(day);
                if ((int)day % 2 == 0) {
                    workTime.Change(new Time(8, 0), new Time(12, 0), "Sala1", true);
                } else {
                    workTime.Change(new Time(12, 0), new Time(20, 0), "Sala1", true);
                }
            }
            WorkerUser doctor1user = new WorkerUser("m", _password.Encrypt("m"), doctor1, WorkerUserRole.Doctor);
            _userRepository.Store(doctor1user);

            Doctor doctor2 = new Doctor("Grzegorz", "Piast");
            foreach (DayOfWeek day in Enum.GetValues(typeof(DayOfWeek))) {
                WorkTime workTime = doctor2.GetWorkTime(day);
                if ((int)day % 2 == 0) {
                    workTime.Change(new Time(12, 0), new Time(20, 0), "Sala2", true);
                } else {
                    workTime.Change(new Time(8, 0), new Time(12, 0), "Sala2", true);
                }
            }
            WorkerUser doctor2user = new WorkerUser("g", _password.Encrypt("g"), doctor2, WorkerUserRole.Doctor);
            _userRepository.Store(doctor2user);

            Worker recepcionist1 = new Worker("Anna", "Adramowicz");
            WorkerUser recepcionist1user = new WorkerUser("a", _password.Encrypt("a"), recepcionist1, WorkerUserRole.Recepcionist);
            _userRepository.Store(recepcionist1user);

            //Pacjenci

            Patient patient1 = new Patient(
                new PersonalData(
                    "Marcin",
                    "Kos",
                    "86121212345",
                    new Address("Szczęśliwa", "12/34", "30-812", "Kraków", "Małopolskie", "123849103")),
                doctor1);
            _patientUserRepository.Store(new PatientUser(String.Empty, patient1));

            Patient patient2 = new Patient(
                new PersonalData(
                "Marcin",
                "Kras",
                "88121215432",
                new Address("Wesoła", "14", "30-842", "Kraków", "Małopolskie", "81239-123")),
                doctor1);
            _patientUserRepository.Store(new PatientUser(String.Empty, patient2));

            Patient patient3 = new Patient(
                new PersonalData(
                "Kasia",
                "Roma",
                "76030313827",
                new Address("Smutna", "12", "31-312", "Kraków", "Małopolskie", "8270-4391")),
                doctor2);
            _patientUserRepository.Store(new PatientUser(String.Empty, patient3));

            Patient patient4 = new Patient(
                new PersonalData(
                "Weronika",
                "Orakian",
                "92837182910",
                new Address("Radosna", "32/2", "31-121", "Kraków", "Małopolskie", "123-18917")),
                doctor2);
            _patientUserRepository.Store(new PatientUser(String.Empty, patient4));

            //Wizyty

            Visit visit1 = new Visit(
                doctor1, patient1, today.AddHours(8));
            _visitRepository.Store(visit1);

            Visit visit2 = new Visit(
                doctor1, patient2,
                doctor1.GetWorkTime(today.DayOfWeek).BeginTime.DateTime(today).AddMinutes(10));
            _visitRepository.Store(visit2);

            Visit visit3 = new Visit(
                doctor1, patient3,
                doctor1.GetWorkTime(today.DayOfWeek).BeginTime.DateTime(today).AddMinutes(20));
            _visitRepository.Store(visit3);

            Visit visit4 = new Visit(
                doctor1, patient4,
                doctor1.GetWorkTime(today.DayOfWeek).BeginTime.DateTime(today).AddMinutes(30));
            _visitRepository.Store(visit4);

            DateTime tomorrow = today.AddDays(1);

            Visit visit5 = new Visit(
                doctor1, patient2,
                doctor1.GetWorkTime(tomorrow.DayOfWeek).BeginTime.DateTime(tomorrow).AddMinutes(10));
            _visitRepository.Store(visit5);

            Visit visit6 = new Visit(
                doctor1, patient4,
                doctor1.GetWorkTime(tomorrow.DayOfWeek).BeginTime.DateTime(tomorrow).AddMinutes(20));
            _visitRepository.Store(visit6);

            //Wpisy

            Entry entry1 = new Entry(
                doctor1, patient1, today.AddMonths(-1).AddHours(8).AddMinutes(10),
                new EntryContent("Powód 1", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry1);

            Entry entry2 = new Entry(
                doctor2, patient1, today.AddMonths(-2).AddHours(9).AddMinutes(25),
                new EntryContent("Powód 2", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry2);

            Entry entry3 = new Entry(
                doctor1, patient1, today.AddMonths(-3).AddHours(11).AddMinutes(16),
                new EntryContent("Powód 3", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry3);

            Entry entry4 = new Entry(
                doctor2, patient2, today.AddMonths(-1).AddHours(8).AddMinutes(10),
                new EntryContent("Powód 1", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry4);

            Entry entry5 = new Entry(
                doctor2, patient2, today.AddMonths(-2).AddHours(9).AddMinutes(25),
                new EntryContent("Powód 2", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry5);

            Entry entry6 = new Entry(
                doctor1, patient2, today.AddMonths(-3).AddHours(11).AddMinutes(16),
                new EntryContent("Powód 3", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry6);

            Entry entry7 = new Entry(
                doctor2, patient3, today.AddMonths(-3).AddHours(9).AddMinutes(25),
                new EntryContent("Powód 1", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry7);

            Entry entry8 = new Entry(
                doctor1, patient3, today.AddMonths(-4).AddHours(11).AddMinutes(16),
                new EntryContent("Powód 2", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry8);

            Entry entry9 = new Entry(
                doctor1, patient4, today.AddMonths(-3).AddHours(9).AddMinutes(25),
                new EntryContent("Powód 1", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry9);

            Entry entry10 = new Entry(
                doctor2, patient4, today.AddMonths(-4).AddHours(11).AddMinutes(16),
                new EntryContent("Powód 2", "Opis choroby", "Zalecenia"));
            _entryRepository.Store(entry10);

        }

        public void Reset()
        {
            Configuration configuration = new Configuration();
            configuration.Configure();
            new SchemaExport(configuration).Execute(false, true, false);

            Worker admin = new Worker("admin", "admin");
            WorkerUser user = new WorkerUser("admin", _password.Encrypt("admin"), admin, WorkerUserRole.Administrator);
            _userRepository.Store(user);
        }
    }
}
